<?php
/**
 * Form_Element
 *
 * класс Form_Element позволяет работать с элементами формы
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @version 1.1
 */

abstract class Form_Element {
  protected $_objARName;
  protected $_arrModelNames;	//массив используемых моделей
	protected $_arrAttr; //массив дополнительных атрибутов
	protected $_name; //атрибут name
	protected $_tabindex; // атрибут tabindex
	protected $_label; //подпись к элементу
	protected $_value = ''; // начальное значение
	protected $_required; // Обзательное для заполнения
	protected $_pattern = ''; // Шаблон заполнения
	protected $_defaultValue = ''; // значение по умолчанию
	protected $_hiddenRow = false; // скрывать троку в таблице (только Для Form_ViewForm)
  //protected $_heading; //заголовок элемента

  protected $_class;//атрибут class
  protected $_style;//атрибут style
  protected $_help;//Текст подсказки
  protected $_afterHelp;//Текст подсказки
  protected $_id;//атрибут id
  protected $_noId;//атрибут id
  protected $_absId;//атрибут id
  protected $_js;//дополнительный js-код
  protected $_htmlAfter;//дополнительный js-код
  protected $_isError;
  protected $_errorText;
  protected $_errorStyle = 1;
  protected $_type;
  protected $_min;
  protected $_max;
  protected $_arrData;
  protected $_skipCustumInput;
  
  protected $_justField = false;
  protected $_disabled = false;
  //protected $_useCorrectMessage = true;//флаг, обозначающий, следует ли выводить сообщение о корректном вводе
  function __construct(array $arrSettings = array(), $fieldName = null) {
    if (isset($fieldName)) {
  	  $this->setSetting('name', $fieldName);
  	  $this->setSetting('id', $fieldName);
  	}  	
  	if ($arrSettings) {
	  	foreach ($arrSettings as $settingName => $settingValue) {
	  		$this->setSetting($settingName, $settingValue);
	  	}
  	}
  }


	/**
	 * Метод устанавливает свойство
	 *
	 * @param string $settingName
	 * @param mixed $settingValue
	 * @param string $additionalAllowedSettings
	 */
	public function setSetting($settingName, $settingValue, $additionalAllowedSettings = null) {
    switch ($settingName) {
    	case 'attr':
    		$this->setArrAttr($settingValue);
    		break;
    	case 'id':
    		$this->setId($settingValue);
    		break;
    	case 'noId':
    		$this->_noId = true;
    		break;
    	case 'absId':
    		$this->setId($settingValue);
    		$this->_absId = true;
    		break;
    	case 'class':
    		$this->setClass($settingValue);
    		break;
    	case 'disabled':
    		if (!empty($settingValue)) $this->_disabled = true;
    		break;
    	case 'name':
    		$this->setName($settingValue);
    		break;
    	case 'tabindex':
    	case 'tabIndex':
    	case 'z-index':
    		$this->setTabindex($settingValue);
    		break;
    	case 'style':
    		$this->setStyle($settingValue);
    		break;
    	case 'help':
    		$this->setHelp($settingValue);
    		break;
    	case 'afterHelp':
    		$this->setAfterHelp($settingValue);
    		break;
    	case 'js':
    		$this->setJs($settingValue);
    		break;
    	case 'label':
    		$this->setLabel($settingValue);
    		break;
    	case 'modelNames':
    		$this->setModelNames($settingValue);
    		break;
    	case 'objARName':
    		$this->setObjARName($settingValue);
    		break;
    	case 'value':
    		$this->setValue($settingValue);
    		break;
    	case 'required':
    		$this->_required = $settingValue;
    		break;
    	case 'requiredOnly':
    		$this->_required = $settingValue;
    		break;
    	case 'pattern':
    		$this->_pattern = $settingValue;
    		break;
    	case 'text': case 'rowspan1': case 'rowspan2':
    		break;
    	case 'justField':
    		$this->_justField = true;
    		break;
    	case 'htmlAfter':
    		$this->_htmlAfter = $settingValue;
    		break;
    	case 'hiddenRow':
    		$this->_hiddenRow = $settingValue;
    		break;
    	case 'defaultValue':
    		$this->setValue($settingValue);
    		$this->setDefaultValue($settingValue);
    		break;
		case 'type':
    		$this->_type = $settingValue;
    		break;
		case 'min':
    		$this->_min = $settingValue;
    		break;
		case 'max':
    		$this->_max = $settingValue;
    		break;
		case 'data':
    		$this->_arrData = $settingValue;
    		break;
		case 'skip-custom-input':
			$this->_skipCustumInput = $settingValue;
			break;
    	default:
    	  throw new Exception('You try to use invalid configuration (' . $settingName . '). The assume settings are: "attr", "justField", "text", "required", "value", "defaultValue", "objARName", "modelNames", "label", "name", "class", "js", "id", "type", "min", "max", "style", "htmlAfter"' . ($additionalAllowedSettings ? ', ' . $additionalAllowedSettings : null));
			  break;
    }
  }
	/**
	 * Устанавливает дополнительный атрибут
	 *
	 * @param string $attr
	 */
	private function setArrAttr(array $attr) {
		$this->_arrAttr = $attr;
	}
	/**
	 * Устанавливает атрибут id
	 *
	 * @param string $id
	 */
	private function setId($id) {
		$this->_id = $id;
	}
	/**
	 * Устанавливает класс html-элемента
	 *
	 * @param string $class
	 */
	private function setClass($class) {
		$this->_class = $class;
	}
	/**
	 * Устанавливает атрибут name
	 *
	 * @param string $name
	 */
	private function setName($name) {
		$this->_name = $name;
	}
	/**
	 * Устанавливает атрибут tabindex
	 *
	 * @param string $name
	 */
	private function setTabindex($tabindex) {
		$this->_tabindex = $tabindex;
	}

	/**
	 * Устанавливает стили
	 *
	 * @param string $style
	 */
	private function setStyle($style) {
		$this->_style = $style;
	}
	/**
	 * Устанавливает текст подсказки
	 *
	 * @param string $help
	 */
	private function setHelp($help) {
		$this->_help = $help;
	}
	/**
	 * Устанавливает текст подсказки
	 *
	 * @param string $afterHelp
	 */
	private function setAfterHelp($afterHelp) {
		$this->_afterHelp = $afterHelp;
	}
	/**
	 * Устанавливает js-код
	 *
	 * @param string $js
	 */
	private function setJs($js) {
		$this->_js = $js;
	}
	/**
	 * Устанавливает подпись к элементу
	 *
	 * @param string $label
	 */
	private function setLabel($label) {
		$this->_label = $label;
	}
	/**
	 * Устанавливает объект, с которым работает форма
	 *
	 * @param string $objARName
	 */
	private function setObjARName($objARName) {
		$this->_objARName = $objARName;
	}
  /**
   * задает значение
   *
   * @param integer $value
   */
  public function setValue($value) {
    $this->_value = $value;
  }
  /**
   * задает значение по умолчанию
   *
   * @param integer $value
   */
  public function setDefaultValue($value) {
    $this->_defaultValue = $value;
  }
	/**
	 * Устанавливает массив моделей
	 *
	 * @param array $modelNames
	 */
	private function setModelNames($modelNames) {
		$this->_arrModelNames = $modelNames;
	}
	
	public function checkForErrors() {
	  $modelsSize = sizeof($this->_arrModelNames);
	  for ($i = 0; $i < $modelsSize; $i++) {
	   if (is_integer($this->_arrModelNames[$i])) {
	    $errText = Exception_ActiveRecord::getExceptionOfModelField($this->_name, $this->_arrModelNames[$i - 1], $this->_arrModelNames[$i]);
	   }
	   else {
	     $errText = Exception_ActiveRecord::getExceptionOfModelField($this->_name, $this->_arrModelNames[$i]);
	     if ($i && !$errText) $errText = Exception_ActiveRecord::getExceptionOfModelField($this->_name, array($this->_arrModelNames[$i - 1], $this->_arrModelNames[$i]));
	   }
	   if ($errText) {
	    $this->_isError = true;
	    $this->_errorText = $errText;
	   }
	  }
	 }
	/*
	public function checkForErrors() {
		$modelsSize = sizeof($this->_arrModelNames);
		for ($i = 0; $i < $modelsSize; $i++) {
			if (is_integer($this->_arrModelNames[$i]))
				$errText = Exception_ActiveRecord::getExceptionOfModelField($this->_name, $this->_arrModelNames[$i - 1], $this->_arrModelNames[$i]);
			else
				$errText = Exception_ActiveRecord::getExceptionOfModelField($this->_name, $this->_arrModelNames[$i]);
			if ($errText) {
				$this->_isError = true;
				$this->_errorText = $errText;
			}
		}
	}
*/

  /**
   * выводит андартные атрибуты элемента
   *
   */
  public function showElementAttributes() {
		// вывод id
		if (empty($this->_noId)) echo ' id="' . $this->getId() . '"';

		// вывод name
		echo ' name="' . $this->getName() . (!empty($this->_multiple) ? '[]' : null) . '"';
		//if ($this->_required) echo ' required';
  	

		// вывод прочит атрибутов
		if (!empty($this->_disabled)) echo ' disabled="disabled"';
		if (isset($this->_class)) echo ' class="' . $this->_class . '"';
		if (isset($this->_style)) echo ' style="' . $this->_style . '"';
		if (isset($this->_style)) echo ' style="' . $this->_style . '"';
		if (isset($this->_tabindex)) echo ' tabindex="' . $this->_tabindex . '"';
		if (isset($this->_js)) echo ' ' . $this->_js;
		if (isset($this->_arrData)) {
			foreach ($this->_arrData as $dataName => $dataValue) {
				echo ' data-' . $dataName . '=' . $dataValue;
			}			
		}
		if (!empty($this->_type)) {
			echo ' type="' . $this->_type . '"';
			if (!empty($this->_min) || $this->_min === 0) echo ' min="' . $this->_min . '"';
			if (!empty($this->_max)) echo ' max="' . $this->_max . '"';
		}
		if (!empty($this->_skipCustumInput)) echo ' skip-custom-input="' . $this->_skipCustumInput . '"';
		//if ($this->_required && (!isset($this->_class) || $this->_class != 'wysiwygAdmin')) echo ' required="required"';
		$this->showAdditionalAttributes();
  }
  /**
   * Получает атрибут id
   *
   * @return string
   */
  public function getId() {
  	$retStr = '';
  	if ($this->_justField) return $this->_id;
		if (($this->_absId)) return $this->_id;
  	if ($this->_arrModelNames) {
	  	foreach ($this->_arrModelNames as $modelName) {
				$retStr .= $modelName . '_';
			}
  	}
		$retStr .= $this->_id;
		return $retStr;
  }

  /**
   * Выводит дополнительные атрибуты
   *
   */
  public function showAdditionalAttributes() {
  	if ($this->_arrAttr && is_array($this->_arrAttr)) {
  		foreach ($this->_arrAttr as $attrName => $attrValue) {
	  		echo ' ' . $attrName . '="' . $attrValue . '"';
  		}
  	}  	
  }
  
  /**
   * Получает атрибут name
   *
   * @return string
   */
  public function getName() {
		$retStr = '';
  	if ($this->_justField)
		  $retStr .= $this->_name;
		else {
			$modelsSize = sizeof($this->_arrModelNames);
			$i = 0;
			if ($this->_arrModelNames) foreach ($this->_arrModelNames as $modelName) {
			  if ($i) $retStr .= '[' . $modelName . ']';
			  else $retStr .= $modelName;
			  $i++;
			}
		  if ($modelsSize) $retStr .= '[' . $this->_name . ']';
		  else $retStr .= $this->_name;
  	}
  	return $retStr;
  }

  /**
   * Добавляет дополнительный атрибут
   *
   * @param string $attrName
   * @param string $attrValue
   * @return bool
   */
  public function setAttr($attrName, $attrValue) {
  	$this->_arrAttr[] = array( $attrName => $attrValue);
  	return true;
  }

  /**
   * формирует сообщение об успехе/ошибке заполнения поля
   *
   * @return string
   */
  public function showAfterElementMessage() {
  	if ($this->_isError) {
  		self::showErrorIco($this->_errorText);
  	}
    //elseif ($useCorrectMessage && $arrSubmit['submited'])
      //$retStr .= '<img src="' . W_IMAGES . 'icons/correct.gif"  class="errOrCor" alt="" />';
		if ($this->_htmlAfter)
		  echo $this->_htmlAfter;
  }
  /**
   * Выводит сообщение об ошибке
   *
   */
  public static function showErrorIco($errText) {
  	if(defined('SKIN') && SKIN == 'octaeder') {
  		echo '<div class="inp-error">';
  			echo new Elm('val-error');
  			echo $errText;
  		echo '</div>';
  	}
  	else echo '<img src="' . W_IMAGES . 'icons/error.gif"  class="errOrCor" alt="" title="' . $errText . '" />';
  }

  /**
   * Отменяет вывод сообщения о корректном вводе
   *
   */
  /*
  public function dontUseCorrectMessage() {
    $this->_useCorrectMessage = false;
  }
  */
  /**
   * Делит массив на 2 части
   *
   * @param string $strArrName
   * @return array
   */
  /*
  public static function divideArrayName($strArrName) {
    $cramp = strpos($strArrName, '['); 
    if (!$cramp) {
      return array($strArrName, null);
    }
    else {
      $cramp2 = strpos($strArrName, ']');
      $strSubArrName =  substr($strArrName, ($cramp + 1), $cramp2 - $cramp - 1);
      if (strlen($strArrName) > ($cramp2 + 1) )
        $strSubArrName .= substr($strArrName, ($cramp2 + 1));
      $strArrName = substr($strArrName, 0, $cramp);
      return array($strArrName, $strSubArrName);
    }
  }
  */


}